home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / inetutil.1 / inetutil / inetutils-1.1 / talkd / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-22  |  6.1 KB  |  228 lines

  1. /*
  2.  * Copyright (c) 1983, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)process.c    8.2 (Berkeley) 11/16/93";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * process.c handles the requests, which can be of three types:
  40.  *    ANNOUNCE - announce to a user that a talk is wanted
  41.  *    LEAVE_INVITE - insert the request into the table
  42.  *    LOOK_UP - look up to see if a request is waiting in
  43.  *          in the table for the local user
  44.  *    DELETE - delete invitation
  45.  */
  46.  
  47. #ifdef HAVE_CONFIG_H
  48. #include <config.h>
  49. #endif
  50.  
  51. #include <sys/param.h>
  52. #include <sys/stat.h>
  53. #include <sys/socket.h>
  54. #include <netinet/in.h>
  55. #ifndef HAVE_OSOCKADDR
  56. #include <osockaddr.h>
  57. #endif
  58. #include <protocols/talkd.h>
  59. #include <netdb.h>
  60. #include <syslog.h>
  61. #include <stdio.h>
  62. #include <string.h>
  63. #include <paths.h>
  64.  
  65. CTL_MSG *find_request();
  66. CTL_MSG *find_match();
  67.  
  68. process_request(mp, rp)
  69.     register CTL_MSG *mp;
  70.     register CTL_RESPONSE *rp;
  71. {
  72.     register CTL_MSG *ptr;
  73.     extern int debug;
  74.  
  75.     rp->vers = TALK_VERSION;
  76.     rp->type = mp->type;
  77.     rp->id_num = htonl(0);
  78.     if (mp->vers != TALK_VERSION) {
  79.         syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  80.         rp->answer = BADVERSION;
  81.         return;
  82.     }
  83.     mp->id_num = ntohl(mp->id_num);
  84.     mp->addr.sa_family = ntohs(mp->addr.sa_family);
  85.     if (mp->addr.sa_family != AF_INET) {
  86.         syslog(LOG_WARNING, "Bad address, family %d",
  87.             mp->addr.sa_family);
  88.         rp->answer = BADADDR;
  89.         return;
  90.     }
  91.     mp->ctl_addr.sa_family = ntohs(mp->ctl_addr.sa_family);
  92.     if (mp->ctl_addr.sa_family != AF_INET) {
  93.         syslog(LOG_WARNING, "Bad control address, family %d",
  94.             mp->ctl_addr.sa_family);
  95.         rp->answer = BADCTLADDR;
  96.         return;
  97.     }
  98.     mp->pid = ntohl(mp->pid);
  99.     if (debug)
  100.         print_request("process_request", mp);
  101.     switch (mp->type) {
  102.  
  103.     case ANNOUNCE:
  104.         do_announce(mp, rp);
  105.         break;
  106.  
  107.     case LEAVE_INVITE:
  108.         ptr = find_request(mp);
  109.         if (ptr != (CTL_MSG *)0) {
  110.             rp->id_num = htonl(ptr->id_num);
  111.             rp->answer = SUCCESS;
  112.         } else
  113.             insert_table(mp, rp);
  114.         break;
  115.  
  116.     case LOOK_UP:
  117.         ptr = find_match(mp);
  118.         if (ptr != (CTL_MSG *)0) {
  119.             rp->id_num = htonl(ptr->id_num);
  120.             rp->addr = ptr->addr;
  121.             rp->addr.sa_family = htons(ptr->addr.sa_family);
  122.             rp->answer = SUCCESS;
  123.         } else
  124.             rp->answer = NOT_HERE;
  125.         break;
  126.  
  127.     case DELETE:
  128.         rp->answer = delete_invite(mp->id_num);
  129.         break;
  130.  
  131.     default:
  132.         rp->answer = UNKNOWN_REQUEST;
  133.         break;
  134.     }
  135.     if (debug)
  136.         print_response("process_request", rp);
  137. }
  138.  
  139. do_announce(mp, rp)
  140.     register CTL_MSG *mp;
  141.     CTL_RESPONSE *rp;
  142. {
  143.     struct hostent *hp;
  144.     CTL_MSG *ptr;
  145.     int result;
  146.  
  147.     /* see if the user is logged */
  148.     result = find_user(mp->r_name, mp->r_tty);
  149.     if (result != SUCCESS) {
  150.         rp->answer = result;
  151.         return;
  152.     }
  153. #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  154.     hp = gethostbyaddr((char *)&satosin(&mp->ctl_addr)->sin_addr,
  155.         sizeof (struct in_addr), AF_INET);
  156.     if (hp == (struct hostent *)0) {
  157.         rp->answer = MACHINE_UNKNOWN;
  158.         return;
  159.     }
  160.     ptr = find_request(mp);
  161.     if (ptr == (CTL_MSG *) 0) {
  162.         insert_table(mp, rp);
  163.         rp->answer = announce(mp, hp->h_name);
  164.         return;
  165.     }
  166.     if (mp->id_num > ptr->id_num) {
  167.         /*
  168.          * This is an explicit re-announce, so update the id_num
  169.          * field to avoid duplicates and re-announce the talk.
  170.          */
  171.         ptr->id_num = new_id();
  172.         rp->id_num = htonl(ptr->id_num);
  173.         rp->answer = announce(mp, hp->h_name);
  174.     } else {
  175.         /* a duplicated request, so ignore it */
  176.         rp->id_num = htonl(ptr->id_num);
  177.         rp->answer = SUCCESS;
  178.     }
  179. }
  180.  
  181. #include <utmp.h>
  182.  
  183. /*
  184.  * Search utmp for the local user
  185.  */
  186. find_user(name, tty)
  187.     char *name, *tty;
  188. {
  189.     struct utmp ubuf;
  190.     int status;
  191.     FILE *fd;
  192.     struct stat statb;
  193.     char line[sizeof(ubuf.ut_line) + 1];
  194.     char ftty[sizeof(_PATH_DEV) - 1 + sizeof(line)];
  195.  
  196.     if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
  197.         fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
  198.         return (FAILED);
  199.     }
  200. #define SCMPN(a, b)    strncmp(a, b, sizeof (a))
  201.     status = NOT_HERE;
  202.     (void) strcpy(ftty, _PATH_DEV);
  203.     while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
  204.         if (SCMPN(ubuf.ut_name, name) == 0) {
  205.             strncpy(line, ubuf.ut_line, sizeof(ubuf.ut_line));
  206.             line[sizeof(ubuf.ut_line)] = '\0';
  207.             if (*tty == '\0') {
  208.                 status = PERMISSION_DENIED;
  209.                 /* no particular tty was requested */
  210.                 (void) strcpy(ftty + sizeof(_PATH_DEV) - 1,
  211.                     line);
  212.                 if (stat(ftty, &statb) == 0) {
  213.                     if (!(statb.st_mode & 020))
  214.                         continue;
  215.                     (void) strcpy(tty, line);
  216.                     status = SUCCESS;
  217.                     break;
  218.                 }
  219.             }
  220.             if (strcmp(line, tty) == 0) {
  221.                 status = SUCCESS;
  222.                 break;
  223.             }
  224.         }
  225.     fclose(fd);
  226.     return (status);
  227. }
  228.